﻿using System;
using System.Collections.Generic;
using System.Configuration;
using System.Linq;
using System.Runtime.Caching;
using System.Runtime.Caching.Configuration;
using Memcached.ClientLibrary;

namespace Catalyst.Caching
{
	public class MemcachedForDataContracts : Memcached
	{
		public MemcachedForDataContracts() : base() { }

		public bool Add<T>(CacheItem item, CacheItemPolicy policy) where T : class
		{
			return Add<T>(item.Key, (T)item.Value, policy, item.RegionName);
		}

		public bool Add<T>(string key, T value, string regionName = null) where T : class
		{
			return Add<T>(key, value, ObjectCache.InfiniteAbsoluteExpiration, regionName);
		}

		public bool Add<T>(string key, T value, CacheItemPolicy policy, string regionName = null) where T : class
		{
			return Add<T>(key, value, policy.AbsoluteExpiration, regionName);
		}

		public bool Add<T>(string key, T value, DateTimeOffset absoluteExpiration, string regionName = null) where T : class
		{
			try
			{
				MemcachedClient cache = GetCache(regionName);
				cache.Add<T>(key, (T)value, absoluteExpiration.DateTime);
				return true;
			}
			catch
			{
				return false;
			}
		}

		public override bool Add(CacheItem item, CacheItemPolicy policy)
		{
			throw new NotImplementedException();
		}

		public override bool Add(string key, object value, string regionName = null)
		{
			throw new NotImplementedException();
		}

		public override bool Add(string key, object value, CacheItemPolicy policy, string regionName = null)
		{
			throw new NotImplementedException();
		}

		public override bool Add(string key, object value, DateTimeOffset absoluteExpiration, string regionName = null)
		{
			throw new NotImplementedException();
		}

		public override CacheItem AddOrGetExisting(CacheItem value, CacheItemPolicy policy)
		{
			throw new NotImplementedException();
		}

		public override object AddOrGetExisting(string key, object value, string regionName = null)
		{
			throw new NotImplementedException();
		}

		public override object AddOrGetExisting(string key, object value, CacheItemPolicy policy, string regionName = null)
		{
			throw new NotImplementedException();
		}

		public override object AddOrGetExisting(string key, object value, DateTimeOffset absoluteExpiration, string regionName = null)
		{
			throw new NotImplementedException();
		}

		public CacheItem AddOrGetExisting<T>(CacheItem value, CacheItemPolicy policy) where T : class
		{
			return new CacheItem(value.Key, AddOrGetExisting<T>(value.Key, (T)value.Value, policy, value.RegionName));
		}

		public T AddOrGetExisting<T>(string key, T value, string regionName = null) where T : class
		{
			return AddOrGetExisting<T>(key, value, ObjectCache.InfiniteAbsoluteExpiration);
		}

		public T AddOrGetExisting<T>(string key, T value, CacheItemPolicy policy, string regionName = null) where T : class
		{
			return (T)AddOrGetExisting<T>(new CacheItem(key, value), policy).Value;
		}

		public T AddOrGetExisting<T>(string key, T value, DateTimeOffset absoluteExpiration, string regionName = null) where T : class
		{
			if (!Contains(key))
			{
				Add<T>(key, value, absoluteExpiration);
			}

			return Get<T>(key);
		}

		public override object Get(string key, string regionName = null)
		{
			throw new NotImplementedException();
		}

		public T Get<T>(string key, string regionName = null) where T : class
		{
			MemcachedClient cache = GetCache(regionName);
			return cache.Get<T>(key);
		}

		public override CacheItem GetCacheItem(string key, string regionName = null)
		{
			throw new NotImplementedException();
		}

		public CacheItem GetCacheItem<T>(string key, string regionName = null) where T : class
		{
			return new CacheItem(key, Get<T>(key));
		}

		public override long GetCount(string regionName = null)
		{
			throw new NotImplementedException();
		}

		public override IDictionary<string, object> GetValues(string regionName, params string[] keys)
		{
			throw new NotImplementedException();
		}

		public override IDictionary<string, object> GetValues(IEnumerable<string> keys, string regionName = null)
		{
			throw new NotImplementedException();
		}

		//public override string Name
		//{
		//    get { throw new NotImplementedException(); }
		//}

		//public override object Remove(string key, string regionName = null)
		//{
		//    return GetCache(regionName).Delete(key);
		//}

		public override void Set(string key, object value, CacheItemPolicy policy, string regionName = null)
		{
			throw new NotImplementedException();
		}

		public override void Set(CacheItem item, CacheItemPolicy policy)
		{
			throw new NotImplementedException();
		}

		public override void Set(string key, object value, DateTimeOffset absoluteExpiration, string regionName = null)
		{
			throw new NotImplementedException();
		}

		public override void Set(string key, object value, string regionName = null)
		{
			throw new NotImplementedException();
		}

		public void Set<T>(string key, T value, CacheItemPolicy policy, string regionName = null) where T : class
		{
			Set<T>(key, value, policy.AbsoluteExpiration, regionName);
		}

		public void Set<T>(CacheItem item, CacheItemPolicy policy) where T : class
		{
			Set<T>(item.Key, (T)item.Value, policy.AbsoluteExpiration, item.RegionName);
		}

		public void Set<T>(string key, T value, string regionName = null) where T : class
		{
			Set<T>(key, value, ObjectCache.InfiniteAbsoluteExpiration, regionName);
		}

		public void Set<T>(string key, T value, DateTimeOffset absoluteExpiration, string regionName = null) where T : class
		{
			MemcachedClient cache = GetCache(regionName);
			cache.Set<T>(key, value, absoluteExpiration.DateTime);
		}

		public override object this[string key]
		{
			get
			{
				throw new NotImplementedException();
			}
			set
			{
				throw new NotImplementedException();
			}
		}
	}
}
